package sparrowGui
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	
	import sparrowGui.item.CListItem;
	import sparrowGui.item.Item;
	import sparrowGui.skin.RadioItemSkin;
	import sparrowGui.utils.PubFun;

	/**
	 * 选多选框
	 * @author Pelephone
	 */	
	public class RadioGroup extends ComponentDraw
	{
		static public const DEFAULT_PREFIX:String = "item_arr";
		
		// 存放item项的容器
		protected var contDP:Sprite;
		
//		protected var _itemClass:Class;		// 列表项类,里面有对项皮肤控制的相关方法，用于自动生成列表
		protected var _itemSkinCla:Class;		// 项皮肤
		protected var _itemsData:Object;		// 列表数据
		
		protected var _selectedIndexs:Array;		// 已选择项的index
		protected var _isRedrawItem:Boolean = false;	// 用于优化是否重新生成Item,降低cpu使用率,
														// 如果为真的话就先把所有item移除,再重新生成新的item放上去
//		protected var parseFun:Function = null;			// 解析子项的方法
		
		/**
		 * 构造选择项
		 * @param data			数据
		 * @param itemSkinCla	列表里面项的皮肤，考虑到表项皮肤经常更换，所以将其放入构造，而项控制类不常换，可放入style
		 * @param parseFun		解析子项的方法,如果为空则自动解析,如果不为空则对通过此参数的方法解析,该方法必须带Object,Item两参数
		 * @param vars			样式
		 */		
		public function RadioGroup(data:Object,itemSkinCla:Class=null,vars:Object=null)
		{
			_itemsData = data || [];
			_selectedIndexs = [];
			_itemSkinCla = (itemSkinCla==null)?RadioItemSkin:itemSkinCla;
			vars = vars || SparrowGUI.getIns().radioVar;
//			if(parseFun!=null) addEventListener(ITEM_UPDATE,parseFun);
			super(vars);
			addEvt();
		}
		
		override protected function init() : void
		{
			contDP = new Sprite();
			addChild(contDP);
			
			if(style.mustSelect && !getSelectedDates().length)
				addSelectedIndex(0);
		}
		
		//添加滚动条事件
		protected function addEvt():void
		{
			contDP.removeEventListener(MouseEvent.CLICK, onItemMouseEvt);
			contDP.addEventListener(MouseEvent.CLICK, onItemMouseEvt);
		}
		
		
		override protected function draw():void
		{
			makeListItems();
			//如果自动高度为真则
			if(style.autoHeight)
				style.height = contDP.height + style.paddingTop + style.paddingBottom;
			
			super.draw();
		}
		
		/**
		 * 创建列表数据.
		 */
		protected function makeListItems():void
		{
			if(style.autoSort && _itemsData && _itemsData.length>0)
				style.itemOdds = PubFun.oddsByDatas(_itemsData[0]);
			
/*			style.pageNum = (style.pageNum<=0)?_itemsData.length:
				(_itemsData.length>style.pageNum)?style.pageNum:_itemsData.length;

			var isSameDS:Boolean = (_itemsData.length && contDP.numChildren
			&& (getItemByIndex(0) is (style.itemClass)) && (_itemSkinCla));
			
			for(var i:int=0; i<_itemsData.length; i++){
				if(_isRedrawItem) createItem(_itemsData[i],i);
				else{
				createItem(_itemsData[i],i,getItemByIndex(i));
				}
			}
			*/
			
			// 优化显示容器，如果当前的皮肤不变，只是数据内容变了则不必清除项再重新生成，只需要将已有的项按新数据重新斌值
			_isRedrawItem = _isRedrawItem || (_itemsData.length>contDP.numChildren);
			
			if(_isRedrawItem) PubFun.clearDisp(contDP);
			
			for(var i:int=0; i<_itemsData.length; i++){
				if(_isRedrawItem) createItem(_itemsData[i],i);
				else createItem(_itemsData[i],i,getItemByIndex(i));
			}
			while(i<contDP.numChildren) getItemByIndex(i++).visible = false;
			
			_isRedrawItem = false;
			arrangeItems();
		}
		
		/**
		 * 创建列表项
		 * @param data
		 * @return 
		 */
		protected function createItem(data:Object,selIndex:int,oItem:Item=null):Item
		{
			if(!oItem){
				var itemSkin:Sprite = (_itemSkinCla!=null && (style.itemClass!=CListItem))?
					(new _itemSkinCla() as Sprite):null;
				var _itCla:Class = style.itemClass || Item;
				oItem = new _itCla(data,itemSkin,null);
				contDP.addChild(oItem);
			}else oItem.update(data);
			
			// 如果有事件监听对象更新则将更新拖管,反则之内部解析
			if(hasEventListener(RadioEvent.ITEM_UPDATE))
				dispatchEvent(new RadioEvent(RadioEvent.ITEM_UPDATE,oItem));
			else parseItem(oItem.itemData,oItem);
			
			oItem.index = selIndex;
			oItem.name = "ListItem" + selIndex;
			oItem.visible = true;
			
			if(style.autoSort && style.itemOdds)
				oItem.autoFill(style.itemOdds);
			
			if(_selectedIndexs.indexOf(oItem.index)>=0) oItem.selected=true;
			else oItem.selected=false;
			
			return oItem;
		}
		
		// 解释子项数据皮肤方法
		protected function parseItem(data:Object, item:Item):void
		{
//			if(parseFun==null){
			if((data is String) || (data is Number)){
				PubFun.setSimpleButtonText(item.itemSkin,String(data));
			}else if(data is Array){
				parseBySkinPrefix(data,item.itemSkin);
			}else{
				parseBySkinName(data,item.itemSkin);
			}
//			}else parseFun(data,item);
		}
		
		// 将item项排列子项的x,y值
		protected function arrangeItems():void
		{
			if(hasEventListener(RadioEvent.ITEM_ARRANGE)){
				for(var i:int=0;i<contDP.numChildren;i++){
					var oItem:Item = contDP.getChildAt(i) as Item;
					dispatchEvent(new RadioEvent(RadioEvent.ITEM_ARRANGE,oItem));
				}
				return;
			}
			PubFun.arrangeDispRC(contDP,style.colNum,style.colWidth,style.rowHeight,style.spacing);
		}
		
		
		///////////////////////////////////
		// event handlers
		///////////////////////////////////
		
		/**
		 * 列表项的鼠标事件
		 */
		protected function onItemMouseEvt(e:MouseEvent):void
		{
			var _item:Item = e.target as Item;
			if(!_item) return;
			switch(e.type){
				case MouseEvent.CLICK:
					addSelectedIndex(_item.index);
					break;
			}
		}
		
		///////////////////////////////////
		// public methods
		///////////////////////////////////
		
		public function update(data:Object):void
		{
			if(!data) data = [];
			_itemsData = data as Array;
			_selectedIndexs = [];
			nextDraw();
		}
		
		public function updateItemAt(index:int,data:Object):void
		{
			var oItem:Item = getItemByIndex(index);
			if(oItem) oItem.update(data);
		}
		
		/**
		 * 通过项index获取项
		 */		
		public function getItemByIndex(i:int):Item
		{
			return contDP.getChildByName("ListItem"+i) as Item;
		}
		
		/**
		 * 通过项数据给列表增加一个项。此项是通过数据和类型添加
		 */
		public function addItem(data:Object):void
		{
			_itemsData.push(data);
			createItem(data,(_itemsData.length-1));
		}
		
		/**
		 * 给指定位置增加表项.
		 * @param data 要增加的项数据.
		 * @param index 要加到的位置索引.
		 */
		public function addItemAt(data:Object, index:int):void
		{
			_itemsData.splice(index, 0, data);
			makeListItems();
		}
		
		/**
		 * Removes the item from the list at the specified index
		 * @param index The index of the item to remove.
		 */
		public function removeItemAt(index:int):void
		{
			_itemsData.splice(index,1);
			makeListItems();
		}
		
		/**
		 * Removes all items from the list.
		 */
		public function removeAll():void
		{
//			PubFun.clearDisp(contDP);
			while(contDP.numChildren) (contDP.removeChildAt(0) as Item).dispose();
			_itemsData = [];
		}
		
		/**
		 * 通过ListItem的名称获取其index
		 */		
		public function getIndexByName(n:String):int
		{
			return int(n.replace("ListItem",""));
		}
		
		/**
		 * 通过项名称获取项
		 */		
		public function getItemByName(n:String):Item
		{
			return contDP.getChildByName(n) as Item;
		}
		
		/**
		 * 获取已选中的项数据
		 * @return 
		 */		
		public function getSelectedDates():Array
		{
			var resArr:Array=[];
			for(var i:int=0;i<_itemsData.length;i++){
				if(_selectedIndexs.indexOf(i)>=0) resArr.push(_itemsData[i]);
			}
			return resArr;
		}
		
		/**
		 * 获取第一条数据
		 * @return 
		 */		
		public function getFirstData():Object
		{
			var arr:Array = getSelectedDates();
			if(arr && arr.length) return arr[0];
			else return null;
		}
		
		//返回选的第一个项,单选时有用
		public function getFirstItem():Item
		{
			if(!_selectedIndexs.length) return null;
			var id:int = _selectedIndexs[0];
			return getItemByIndex(id);
		}
		
		/**
		 * Sets / gets the index of the selected list item.
		 */
		public function addSelectedIndex(value:int):void
		{
			// 如果至少得选一项为真
			if(style.mustSelect && _selectedIndexs.indexOf(value)>=0
				&& _selectedIndexs.length==1) return;
			
			var ind:int = _selectedIndexs.indexOf(value);
			if(ind<0){
				if(style.multiSelect)
					_selectedIndexs.push(value);
				else
					_selectedIndexs = [value];
			}else{
				if(style.multiSelect)
					_selectedIndexs.splice(ind,1);
				else
					_selectedIndexs = []
			}
			
			selectFresh();
			
			dispatchEvent(new RadioEvent(RadioEvent.ITEM_SELECT,getItemByIndex(value)));
		}
		
		/**
		 * 全选
		 * 一定要是多选打开才能全选,否则无效果
		 */		
		public function selectAll():void
		{
			if(!style.multiSelect) return;
			for(var i:int=0;i<contDP.numChildren;i++){
				var oItem:Item = contDP.getChildAt(i) as Item;
				if(!oItem) continue;
				_selectedIndexs.push(oItem.index);
				oItem.selected=true;
			}
		}
		
		/**
		 * 全部取消选择
		 */
		public function unSelectAll():void
		{
			_selectedIndexs = [];
			selectFresh();
		}
		
		/**
		 * 单多选之后按_selectedIndexs数组重刷显示
		 */
		protected function selectFresh():void
		{
			for(var i:int=0;i<contDP.numChildren;i++){
				var oItem:Item = contDP.getChildAt(i) as Item;
				if(!oItem) continue;
				if(_selectedIndexs.indexOf(oItem.index)>=0){
					oItem.selected=true;
				}else
					oItem.selected=false;
			}
		}
		
		public function get selectedIndexs():Array
		{
			return _selectedIndexs;
		}
		
		public function get panHeight():Number
		{
			return height;
		}
		
		// 每行的高
		public function set rowHeight(val:int):void
		{
			style.rowHeight = val;
		}
		
		// 每行的高
		public function get rowHeight():int
		{
			return style.rowHeight;
		}
		
		// 间隔
		public function set spacing(val:int):void
		{
			style.spacing = val;
		}
		
		// 间隔
		public function get spacing():int
		{
			return style.spacing;
		}
		
		// 每列的宽
		public function set colWidth(val:int):void
		{
			style.colWidth = val;
		}
		
		// 每列的宽
		public function get colWidth():int
		{
			return style.colWidth;
		}
		
		// 每行N列
		public function set colNum(val:int):void
		{
			style.colNum = val;
		}
		
		// 每行N列
		public function get colNum():int
		{
			return style.colNum;
		}
		
		/**
		 * 是否多选
		 */
		public function set multiSelect(val:Boolean):void
		{
			style.multiSelect = val;
		}
		
		/**
		 * 是否多选
		 */
		public function get multiSelect():Boolean
		{
			return style.multiSelect;
		}
		
		/**
		 * Sets / gets the list of items to be shown.
		 
		public function set itemsData(value:Object):void
		{
			_itemsData = value;
		}*/
		public function get itemsData():Object
		{
			return _itemsData;
		}
		
		override public function dispose():void
		{
			removeAll();
			removeChild(contDP);
			contDP			= null;
			_itemsData 		= null;
			_selectedIndexs = null;
			_itemSkinCla	= null;
//			parseFun		= null;
			super.dispose();
		}
		
		// 将数据解析到项里的文本
		public static function parseToTxt(data:Object,itemSkin:DisplayObjectContainer):void
		{
			var tf:TextField = PubFun.findChild(itemSkin, TextField) as TextField;
//			trace(data,'|',itemSkin.numChildren,tf.name,itemSkin.parent.name);
			tf.htmlText = String(data);
		}
		
		// 将数据按数据项的前缀字符解析到皮肤
		public static function parseBySkinPrefix(data:Object,itemSkin:DisplayObjectContainer):void
		{
			var prefix:String = DEFAULT_PREFIX;		//"item_arr"
			PubFun.batParseArrTodisp((data as Array),itemSkin,prefix);
		}
		
		// 将数据与皮肤同名的属性斌值到皮肤
		public static function parseBySkinName(data:Object,itemSkin:DisplayObjectContainer):void
		{
			if(!data) return;
			PubFun.batParseObjTodisp(data,itemSkin);
		}
	}
}